home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-28 | 7.3 KB | 336 lines | [TEXT/MPS ] |
- ;
- ; File: ODMathM.a
- ;
- ; Contains: xxx put contents here xxx
- ;
- ; Owned by: Jens Alfke
- ;
- ; Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
- ;
- ; Change History (most recent first):
- ;
- ; <3> 6/27/96 TJ Reverted to orignal source.
- ; <2> 5/31/96 JA CW68K: Moved "_$" headers first to work
- ; around CW68K linker bug.
- ;
- ; To Do:
- ;
- ; This file defines more routines than we need. For now I'm
- ; leaving the extra ones here in case we need 'em later.
- ; These routines are needed (on the Mac) only for 68k.
- ; PowerPC versions are already in the PowerMac Toolbox.
- ; In Progress:
- ;
-
- Machine MC68020
- MC68881
- Case On
- Blanks Off
-
- NuRuntime equ 1
-
- negativeInfinity Equ $80000000
- frac1 Equ $40000000
-
- DataRefs Relative
- Import (lastSinCosAngle,lastSine,lastCosine):Data
-
- ; fixed ODFixedMultiply(fixed a, fixed b)
- ODFixedMultiply Func Export
- _$ODFixedMultiply Func Export
- move.l (sp)+,a0
- move.l (sp),d1
- muls.l 4(sp),d0:d1
- moveq #0,d2
- add.l #$00008000,d1
- addx.l d2,d0
- swap d1
- swap d0
- move d1,d0
- addq.l #8,sp
- jmp (a0)
-
-
- ; fixed ODFixedDivide(fixed a, fixed b)
- ODFixedDivide Func Export
- _$ODFixedDivide Func Export
- move.l (sp)+,a0
- move.l 4(sp),d2 get b
- beq.s @div0
- bpl.s @1
- neg.l d2
- @1 asr.l #1,d2
- move.l (sp),d0 get a
- bpl.s @2
- neg.l d2
- @2 swap d0
- move d0,d1
- ext.l d1
- clr.w d0
- add.l d2,d0
- bfexts d2{0:1},d2
- addx.l d2,d1
- divs.l 4(sp),d1:d0
- bvc.s @3
- move.l 4(sp),d2 get b
- @div0 eor.l d2,(sp)
- bmi.s @div1
- move.l #$7fffffff,d0
- addq.l #8,sp
- jmp (a0)
- @div1 move.l #$80000000,d0
- @3 addq.l #8,sp
- jmp (a0)
-
-
- ; long ODMultiplyDivide(long a, long b, long c)
- ODMultiplyDivide Func Export
- _$ODMultiplyDivide Func Export
- move.l (sp)+,a0
- lea (sp),a1 get parameters
- move.l (a1)+,d0 get a
- move.l (a1)+,d1 get b
- move.l (a1),d2 get c
- beq.s @div0
- bpl.s @1
- neg.l d2
- @1 asr.l #1,d2
- muls.l d1,d1:d0 compute a*b
- bpl.s @2
- neg.l d2
- @2 add.l d2,d0
- bfexts d2{0:1},d2
- addx.l d2,d1
- divs.l (a1),d1:d0 compute a*b/c
- bvc.s @3
- move.l (a1),d0
- @div0 eor.l d1,d0
- bmi.s @div1
- move.l #$7fffffff,d0
- bra.s @3
- @div1 move.l #$80000000,d0
- @3 lea 12(sp),sp
- jmp (a0)
-
- ;short ODFirstBit(long x)
- ODFirstBit Func Export
- _$ODFirstBit Func Export
- move.l (sp)+,a0 get return address
- move.l (sp),d0 get x
- bfffo d0{0:0},d1
- moveq #31,d0
- sub.w d1,d0
- addq.l #4,sp
- jmp (a0)
-
- ; fract ODFractMultiply(fract a, fract b)
- ODFractMultiply Func Export
- _$ODFractMultiply Func Export
- move.l (sp)+,a0
- move.l (sp),d1
- muls.l 4(sp),d0:d1
- moveq #0,d2
- add.l #$20000000,d1
- addx.l d2,d0
- lsl.l #2,d0 2.30 (toss overflow bits)
- rol.l #2,d1
- and #3,d1 get high 2 bits of low long
- or d1,d0
- addq.l #8,sp
- jmp (a0)
-
-
- ; fixed ODFractDivide(fract a, fract b)
- ODFractDivide Func Export
- _$ODFractDivide Func Export
- move.l (sp)+,a0
- move.l 4(sp),d2 get b
- beq.s @div0
- bpl.s @1
- neg.l d2
- @1 move.l (sp),d1 get a
- bpl.s @2
- neg.l d2
- @2 clr.l d0
- asr.l #1,d1
- roxr.l #1,d0
- add.l d2,d0
- bfexts d2{0:1},d2
- addx.l d2,d1
- asr.l #1,d1
- roxr.l #1,d0
- divs.l 4(sp),d1:d0
- bvc.s @3
- move.l 4(sp),d2 get b
- @div0 eor.l d2,(sp)
- bmi.s @div1
- move.l #$7fffffff,d0
- addq.l #8,sp
- jmp (a0)
- @div1 move.l #$80000000,d0
- @3 addq.l #8,sp
- jmp (a0)
-
-
- ; fract ODFractSinCos(fixed radians, fract *b)
- ;
- ; ODFractSinCos requires the NuRuntime Prolog
- ; because it uses xxx(A5) relative references to data constants and so must
- ;"switch" A5
- ODFractSinCos Func Export
- IF NuRuntime THEN
- MOVE.L (A1),A5
- ENDIF
- _$ODFractSinCos Func Export
- move.l (sp)+,a0
- move.l (sp),d0 get degree
- cmp.l lastSinCosAngle(A5),d0
- beq.s @useOld
- move.l d0,lastSinCosAngle(A5)
- ;
- ; (original code expected input in degrees; remove this)
- ; fmovecr.x #0,fp0 get π
- ; fdiv.w #180,fp0 compute 1 degree in radians
- ; fmul.l d0,fp0 multiply by angle
- ; here's what the above 3 instructions became:
- fmove.l d0,fp0 angle already in radians
- ; (end fix)
- fscale.w #-16,fp0 bias by 16
- fsincos.x fp0,fp1:fp0
- fscale.w #30,fp0 bias by 30
- fmove.l fp0,d0
- fscale.w #30,fp1 bias by 30
- move.l 4(sp),a1
- fmove.l fp1,(a1)
- move.l d0,lastSine(A5)
- move.l (a1),lastCosine(A5)
- addq.l #8,sp
- jmp (a0)
- @useOld
- move.l 4(sp),a1 get b
- move.l lastSine(A5),d0
- move.l lastCosine(A5),(a1)
- addq.l #8,sp
- jmp (a0)
-
-
- ; wide *ODWideMultiply(long src1, long src2, wide *dst)
- ODWideMultiply Func Export
- _$ODWideMultiply Func Export
- move.l 4(sp),d0
- muls.l 8(sp), d1:d0
- move.l 12(sp),a0
- move.l d1,(a0)+
- move.l d0,(a0)
- move.l 12(sp),d0
- rtd #12
-
-
- ; long ODWideDivide(wide *num, long denom, long *rem)
- ODWideDivide Func Export
- _$ODWideDivide Func Export
- link a6,#-2
- moveq #-1,d0
- cmp.l 16(a6),d0 if (rem == (void *)-1)
- seq -1(a6) set check
- bne.s @noCheck
- clr.l 16(a6) rem = 0
- @noCheck
- move.l 8(a6),a0 get num
- move.l (a0)+,d1
- move.l (a0),d0
- move.l 12(a6),d2 get denom
- beq.s @div0
- bpl.s @1
- neg.l d2
- @1 tst.l 16(a6) check rem
- bne.s @3
- lsr.l #1,d2
- tst.l d1
- bpl.s @2
- neg.l d2
- @2 add.l d2,d0
- bfexts d2{0:1},d2
- addx.l d2,d1
- @3 divs.l 12(a6),d1:d0
- bvc.s @ok
- move.l 12(a6),d2
- @div0 tst.b -1(a6) check check
- bne.s @div1
- eor.l d1,d2
- bmi.s @div1
- move.l #$7FFFFFFF,d0
- bra.s @div2
- @div1 move.l #$80000000,d0
- @div2 move.l #$80000000,d1
- @ok move.l 16(a6),d2 get rem
- beq.s @done
- move.l d2,a0
- move.l d1,(a0)
- @done unlk a6
- rtd #12
-
- ; long ODWideSquareRoot(wide *src)
- ODWideSquareRoot Func Export
- _$ODWideSquareRoot Func Export
- move.l (sp)+,a0
- move.l #$80000000,d1
- fmove.l d1,fp1
- move.l (sp),a1 Get src
- move.l (a1)+,d0 Get hi long
- add.l d1,d0 Offset for sign
- fmove.l d0,fp0 Move to FP0
- fsub.x fp1,fp0 Compensate for offset
- fscale.w #32,fp0 Shift by 32
- move.l (a1),d0 Get lo long
- add.l d1,d0 Offset for sign
- fadd.l d0,fp0 Add to FP0
- fsub.x fp1,fp0 Compensate for offset
- fsqrt.x fp0 The whole point
- fadd.x fp1,fp0 Offset for sign
- fmove.l fp0,d0 Pass result to D0
- sub.l d1,d0 Compensate for offset
- addq.l #4,sp
- jmp (a0)
-
- ;fract ODFractCubeRoot(fract x)
- ODFractCubeRoot Func Export
- _$ODFractCubeRoot Func Export
- move.l (sp)+,a0 ;get return address
- move.l (sp),d0 ;get x
- beq.s @2
- smi d1 ;save the sign
- bpl.s @1
- neg.l d0
- @1 fmove.l d0,fp0
- flogn fp0 ;take its logarithm
- fdiv.w #3,fp0
- fetox fp0 ;exponentiate
- fscale.w #20,fp0 ;scale for fract
- fmove.l fp0,d0
- tst.b d1 ;check the sign
- beq.s @2
- neg.l d0
- @2 addq.l #4,sp
- jmp (a0)
-
-
- IF NuRuntime THEN
-
- XVector ODFixedMultiply:0
- XVector ODFixedDivide:0
- XVector ODMultiplyDivide:0
- XVector ODFirstBit:0
- XVector ODFractMultiply:0
- XVector ODFractDivide:0
-
- XVector ODFractSinCos:0
-
- XVector ODWideMultiply:0
- XVector ODWideDivide:0
- XVector ODWideSquareRoot:0
- XVector ODFractCubeRoot:0
-
- ENDIF
-
- End